package top.codetheory.thread._001_打断;

import lombok.extern.slf4j.Slf4j;

/**
 * @author: CodeTheory
 * @since: 2024/4/21 下午7:00
 **/
@Slf4j
public class _006_多线程下的计数问题 {

    private static int count = 0;

    public static void main(String[] args) {
        try {
//            test1();
//            test2();
            int a = 0, b = 0;
            for (int i = 0; i < 100; i++) {
                count = 0;
                test3();
                if (count >= 0) {
                    a++;
                } else {
                    b++;
                }
            }
            log.info("循环100次, count为正的次数:{}, count为负的次数:{}", a, b);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 按理来说, 两个线程一个加5000次, 一个减5000次, 最后的结果应该为0, 但是却不是 <br>
     * <img src="https://gitee.com/codetheory/img-on1/raw/master/img01/1713697492540-2024-4-2119:04:52.png"  />
     */
    public static void test1() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                count++;
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                count--;
            }
        }, "t2");

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        log.info("count={}", count);

    }

    /**
     * 通过加锁的方式, 保证线程安全, 最后的结果为0 <br>
     * <img src="https://gitee.com/codetheory/img-on1/raw/master/img01/1713716278465-2024-4-2200:17:58.png"  />
     */
    public static void test2() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (Object.class) {
                    count++;
                }
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (Object.class) {
                    count--;
                }
            }
        }, "t2");

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        log.info("count={}", count);
    }

    public static void test3() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (Object.class) {
                    count++;
                }
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                count--;
            }
        }, "t2");

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        log.info("count={}", count);
    }
}